package cn.edu.swu.miniwebsvr.handler;

import cn.edu.swu.miniwebsvr.core.Config;
import cn.edu.swu.miniwebsvr.core.Handler;
import cn.edu.swu.miniwebsvr.core.Parameter;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
 * 默认请求处理器，负责处理静态资源文件的请求（如HTML、图片、CSS等）。
 * 当请求未匹配到其他处理器时，使用此类尝试从Web根目录读取对应文件并返回；
 * 若文件不存在则返回404，文件读取异常则返回500错误。
 */
public class DefaultHandler implements Handler {
    private static final Map<String, String> CONTENT_TYPE_MAPPING = new HashMap<>();
    static {
        CONTENT_TYPE_MAPPING.put("html", "text/html; charset=UTF-8");
        CONTENT_TYPE_MAPPING.put("css", "text/css");
        CONTENT_TYPE_MAPPING.put("js", "application/javascript");
        CONTENT_TYPE_MAPPING.put("jpg", "image/jpeg");
        CONTENT_TYPE_MAPPING.put("jpeg", "image/jpeg");
        CONTENT_TYPE_MAPPING.put("png", "image/png");
        CONTENT_TYPE_MAPPING.put("gif", "image/gif");
        CONTENT_TYPE_MAPPING.put("txt", "text/plain; charset=UTF-8");
    }
    @Override
    public void handle(Parameter request, OutputStream response) {
        // TODO: [学号/姓名]
        // 1. 获取请求路径（可能需要将 / 映射到 index.html）
        // 2. 根据 Config.getWebRoot() 构建完整文件路径
        Path filePath = Paths.get(Config.getInstance().getWebRoot(), request.getUrl().equals("/") ? "index.html" : request.getUrl().substring(1));

        try {
            if (Files.exists(filePath) && !Files.isDirectory(filePath)) {
                byte[] fileBytes = Files.readAllBytes(filePath);

                // TODO: [学号/姓名] 确定并设置正确的 Content-Type (例如 text/html, image/jpeg 等)
                // 2. 确定并设置正确的Content-Type：优先用手动映射，再用 probeContentType，最后 fallback 为二进制流
                String contentType = Files.probeContentType(filePath) != null ? Files.probeContentType(filePath) : "application/octet-stream";

                // 写入 200 OK 响应头
                response.write(("HTTP/1.1 200 OK\r\n").getBytes());
                response.write(("Content-Type: " + contentType + "\r\n").getBytes());
                response.write(("Content-Length: " + fileBytes.length + "\r\n").getBytes());
                response.write(("\r\n").getBytes());

                // 写入文件内容
                response.write(fileBytes);
            } else {
                // 文件不存在或路径错误，返回 404
                String content = "<h1>404 Not Found</h1><p>The requested resource " + request.getUrl() + " was not found.</p>";
                response.write(("HTTP/1.1 404 Not Found\r\n").getBytes());
                response.write(("Content-Type: text/html; charset=UTF-8\r\n").getBytes());
                response.write(("Content-Length: " + content.getBytes().length + "\r\n").getBytes());
                response.write(("\r\n").getBytes());
                response.write(content.getBytes());
            }
        } catch (IOException e) {
            // TODO: [学号/姓名] 文件读取异常，返回 500 Internal Server Error
            // 文件读取/写入异常，返回500 Internal Server Error
            try {
                String errorContent = "<h1>500 Internal Server Error</h1><p>Server encountered an error while processing the request.</p>";
                byte[] errorBytes = errorContent.getBytes();
                response.write(("HTTP/1.1 500 Internal Server Error\r\n").getBytes());
                response.write(("Content-Type: text/html; charset=UTF-8\r\n").getBytes());
                response.write(("Content-Length: " + errorBytes.length + "\r\n").getBytes());
                response.write(("\r\n").getBytes());
                response.write(errorBytes);
            } catch (IOException ignore) {
                // 若发送500响应时也出错，直接忽略（客户端可能已断开）
            }
            // 打印异常日志，便于调试
            e.printStackTrace();
        } finally {
            try {
                response.flush();
            } catch (IOException e) { /* ignore */ }
        }
    }
}
